﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq.Expressions;
using System.Text;
using System.Collections.Concurrent;
using System.Threading.Tasks;
using System.Linq;

namespace CNative.DbUtils
{
    #region SelectSqlBuilder
    internal class SelectSqlBuilder : BaseSqlBuilder, ISelectSqlBuilder
    {
        #region var
        protected readonly HashSet<string> OrderbyList = new HashSet<string>();
        protected readonly HashSet<string> GroupbyList = new HashSet<string>();
        protected readonly HashSet<string> HavingList = new HashSet<string>();
        protected readonly HashSet<string> JoingList = new HashSet<string>();

        public SelectSqlBuilder(IDbHelper _db) : base(_db)
        {
        }
        #endregion

        #region From
        /// <summary>
        /// 开始查询
        /// </summary>
        /// <typeparam name="TClass"></typeparam>
        /// <param name="fields"></param>
        /// <returns></returns>
        public new ISelectSqlBuilder From<TClass>(string tableAlias = "") where TClass : class, new()
        {
            tupleTableInfo = base.From<TClass>(tableAlias);
            return this;
        }
        /// <summary>
        /// 开始查询(指定查询字段)
        /// </summary>
        /// <typeparam name="TClass"></typeparam>
        /// <param name="fields"></param>
        /// <returns></returns>
        public ISelectSqlBuilder From<TClass>(Expression<Func<TClass, dynamic>> fields = null, string tableAlias = "") where TClass : class, new()
        {
            tupleTableInfo = base.From<TClass>(tableAlias);
            //-----------------------------------------------------------------------------------------------------------
            if (fields != null)
            {
                Fields(fields, tableAlias);
            }
            return this;
        }
        #endregion
        #region Fields
        /// <summary>
        /// 添加查询字段
        /// </summary>
        /// <typeparam name="TClass"></typeparam>
        /// <param name="field"></param>
        /// <returns></returns>
        public ISelectSqlBuilder Fields<TClass>(Expression<Func<TClass, dynamic>> fields, string tableAlias = "") where TClass : class, new()
        {
            var tableInfo = GetTableInfo<TClass>(tableAlias);
            try
            {
                var dicfields = BuildFields(fields, null, tableInfo.Item2);
                if (dicfields.Count > 0)
                {
                    dicfields.ForEach(dic =>
                    {
                        var col = tableInfo.Item1.GetColumn(dic.Key);
                        if (dic.Value.Item3 == typeof(FieldExpr))
                            FieldList.Add($"{dic.Value.Item2} AS {dic.Key}");
                        else
                            FieldList.Add($"{dic.Value.Item1}");
                    });
                }
                else
                {
                    FieldList.Add($"{tableInfo.Item2}*");
                }
            }
            catch (Exception ex)
            {
                if (ex.Message == "未指定目标列")
                {
                    var fieds = new List<string>(ExpressionHelper.GetMemberNames(fields?.Body, db.SqlDbProvider, tableInfo.Item2));
                    if (fieds.Count > 0)
                    {
                        fieds.ForEach(fieldname => FieldList.Add($"{fieldname}"));
                    }
                }
            }
            return this;
        }
        /// <summary>
        /// 添加查询字段
        /// </summary>
        /// <param name="fields"></param>
        /// <returns></returns>
        public ISelectSqlBuilder Fields(params string[] fields)
        {
            if (fields?.Length > 0)
            {
                fields.ForEach(fieldname => FieldList.Add($"{fieldname.Trim(',')}"));
            }
            return this;
        }
        #endregion
        #region Top
        /// <summary>
        /// 最多返回记录数
        /// </summary>
        /// <param name="top"></param>
        /// <returns></returns>
        public ISelectSqlBuilder Top(int top = 1000)
        {
            _Top = top;
            return this;
        }
        #endregion
        #region Where
        /// <summary>
        /// 添加条件表达式
        /// </summary>
        /// <typeparam name="TClass"></typeparam>
        /// <param name="where"></param>
        /// <returns></returns>
        public ISelectSqlBuilder Where<TClass>(Expression<Func<TClass, bool>> where, bool isAnd = true, string tableAlias = "") where TClass : class, new()
        {
            BuildWhere(sqlent, where, isAnd, tableAlias);
            return this;
        }
        /// <summary>
        /// 添加条件表达式
        /// </summary>
        /// <param name="whereStr"></param>
        /// <returns></returns>
        public ISelectSqlBuilder Where(string whereStr, params CNDbParameter[] dbParameters)
        {
            if (whereStr.IsNotNullOrEmpty())
            {
                whereStr = whereStr.Replace("@", paramKeyword).Replace(":", paramKeyword).Replace("?", paramKeyword);
                WhereList.Add(whereStr);
            }
            return this;
        }
        #endregion
        #region OrderBy/OrderByDescending
        /// <summary>
        /// 按列排序，OrderBy(a => a.Time)
        /// </summary>
        /// <typeparam name="TMember"></typeparam>
        /// <param name="column">单个列</param>
        /// <returns></returns>
        public ISelectSqlBuilder OrderBy<TClass>(Expression<Func<TClass, dynamic>> column, string tableAlias = "") where TClass : class, new()
        {
            var tableInfo = GetTableInfo<TClass>(tableAlias);
            var fieds = new List<string>(ExpressionHelper.GetMemberNames(column?.Body, db.SqlDbProvider, tableInfo.Item2));
            if (fieds?.Count > 0)
            {
                OrderbyList.Add($"{fieds[0]} ASC");
            }
            return this;
        }
        /// <summary>
        /// 按列倒向排序，OrderByDescending(a => a.Time)
        /// </summary>
        /// <param name="column">单个列</param>
        /// <returns></returns>
        public ISelectSqlBuilder OrderByDescending<TClass>(Expression<Func<TClass, dynamic>> column, string tableAlias = "") where TClass : class, new()
        {
            var tableInfo = GetTableInfo<TClass>(tableAlias);
            var fieds = new List<string>(ExpressionHelper.GetMemberNames(column?.Body, db.SqlDbProvider, tableInfo.Item2));
            if (fieds?.Count > 0)
            {
                OrderbyList.Add($"{fieds[0]} DESC");
            }
            return this;
        }
        #endregion
        #region GroupBy
        /// <summary>
        /// 按列分组查询
        /// GroupBy<TClass>(a => a.Time) 或者 GroupBy<TClass>(a => new{a.Time,a.Name})
        /// </summary>
        /// <typeparam name="TClass"></typeparam>
        /// <param name="column">列集合</param>
        /// <returns></returns>
        public ISelectSqlBuilder GroupBy<TClass>(Expression<Func<TClass, dynamic>> column, string tableAlias = "") where TClass : class, new()
        {
            var tableInfo = GetTableInfo<TClass>(tableAlias);
            var fieds = new List<string>(ExpressionHelper.GetMemberNames(column?.Body, db.SqlDbProvider, tableInfo.Item2));
            if (fieds?.Count > 0)
            {
                fieds.ForEach(fied =>
                {
                    GroupbyList.Add(fied);
                });
            }
            return this;
        }
        /// <summary>
        /// HAVING 子句可以筛选分组后的各组数据
        /// </summary>
        /// <typeparam name="TClass"></typeparam>
        /// <param name="expression">HAVING aggregate_function(column_name) operator value</param>
        /// <returns></returns>
        public ISelectSqlBuilder Having<TClass>(Expression<Func<TClass, bool>> having, string tableAlias = "") where TClass : class, new()
        {
            var havingStr = BuildWhereExp(sqlent, having, true, tableAlias);
            if (havingStr.IsNotNullOrEmpty())
            {
                HavingList.Add(havingStr);
            }
            return this;
        }
        #endregion

        #region InnerJoin/LeftJoin/RightJoin
        /// <summary>
        /// 等值联接
        /// </summary>
        /// <typeparam name="TClassA">A表</typeparam>
        /// <typeparam name="TClassB">B表</typeparam>
        /// <param name="JoinWhere">关联条件</param>
        /// <returns>只返回两个表中联结字段相等的行</returns>
        public ISelectSqlBuilder InnerJoin<TClassA, TClassB>(Expression<Func<TClassA, TClassB, bool>> JoinWhere, string tableAliasB = "") where TClassA : class, new() where TClassB : class, new()
        {
            JoinWhere.ArgumentNullException("InnerJoin 关联条件不能为空");
            var joinStr = BuildJoinOn(JoinType.Inner, sqlent, JoinWhere, tableAliasB);
            if (joinStr.IsNotNullOrEmpty())
            {
                JoingList.Add(joinStr);
            }
            return this;
        }
        /// <summary>
        /// 左联接
        /// </summary>
        /// <typeparam name="TClassA">A表</typeparam>
        /// <typeparam name="TClassB">B表</typeparam>
        /// <param name="JoinWhere">关联条件</param>
        /// <returns>返回包括左表中的所有记录和右表中联结字段相等的记录</returns>
        public ISelectSqlBuilder LeftJoin<TClassA, TClassB>(Expression<Func<TClassA, TClassB, bool>> JoinWhere, string tableAliasB = "") where TClassA : class, new() where TClassB : class, new()
        {
            JoinWhere.ArgumentNullException("LeftJoin 关联条件不能为空");
            var joinStr = BuildJoinOn(JoinType.Left, sqlent, JoinWhere, tableAliasB);
            if (joinStr.IsNotNullOrEmpty())
            {
                JoingList.Add(joinStr);
            }
            return this;
        }
        /// <summary>
        /// 右联接
        /// </summary>
        /// <typeparam name="TClassA">A表</typeparam>
        /// <typeparam name="TClassB">B表</typeparam>
        /// <param name="JoinWhere">关联条件</param>
        /// <returns>返回包括右表中的所有记录和左表中联结字段相等的记录</returns>
        public ISelectSqlBuilder RightJoin<TClassA, TClassB>(Expression<Func<TClassA, TClassB, bool>> JoinWhere, string tableAliasB = "") where TClassA : class, new() where TClassB : class, new()
        {
            JoinWhere.ArgumentNullException("RightJoin 关联条件不能为空");
            var joinStr = BuildJoinOn(JoinType.Right, sqlent, JoinWhere, tableAliasB);
            if (joinStr.IsNotNullOrEmpty())
            {
                JoingList.Add(joinStr);
            }
            return this;
        }

        /// <summary>
        /// 全联接
        /// </summary>
        /// <typeparam name="TClassB">B表</typeparam>
        /// <param name="JoinWhere">关联条件</param>
        /// <returns>只要其中某个表存在匹配，FULL JOIN 关键字就会返回行</returns>
        public ISelectSqlBuilder FullJoin<TClassA, TClassB>(Expression<Func<TClassA, TClassB, bool>> JoinWhere, string tableAliasB = "") where TClassA : class, new() where TClassB : class, new()
        {
            JoinWhere.ArgumentNullException("RightJoin 关联条件不能为空");
            var joinStr = BuildJoinOn(JoinType.FULL, sqlent, JoinWhere, tableAliasB);
            if (joinStr.IsNotNullOrEmpty())
            {
                JoingList.Add(joinStr);
            }
            return this;
        }
        #endregion

        #region Count/Exists
        /// <summary>
        /// 判断实体是否存在表中
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public bool Exists<TClass>(Expression<Func<TClass, bool>> where) where TClass : class, new()
        {
            return base.Exists(where);
        }
        /// <summary>
        /// 通过条件查询表的记录数
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public long Count<TClass>(Expression<Func<TClass, bool>> where) where TClass : class, new()
        {
            BuildWhere(sqlent, where);
            return base.Count(where);
        }
        #endregion

        #region QueryPagingList
        /// <summary>
        /// 分页查询返回实体集合
        /// </summary>
        /// <typeparam name="TClass"></typeparam>
        /// <param name="pageIndex">第几页，从1开始</param>
        /// <param name="pageSize">每页多少</param>
        /// <param name="totalNumber">查询的记录总数量</param>
        /// <returns></returns>
        public List<TClass> QueryPagingList<TClass>(int pageIndex, int pageSize, ref long totalNumber) where TClass : class, new()
        {
            #region sql
            var joinStr = "";
            if (JoingList.Count > 0)
            {
                joinStr = string.Join(" ", JoingList);
                fromStr += joinStr;
            }
            //-----------------------------------------------------------------------------------------------------------------
            var fieldsStr = FieldList.Count > 0 ? string.Join(", ", FieldList) : "*";
            var wheresStr = "1=1";
            if (WhereList.Count > 0)
            {
                wheresStr = string.Join(" ", WhereList).Trim()
                    .ReplaceIgnoreCase("WHERE", "").TrimPrefixName("AND").TrimPrefixName("OR");
            }
            //-----------------------------------
            var orderbyStr = "";
            if (OrderbyList.Count == 0)
            {
                var tableInfo = GetTableInfo<TClass>();
                var tb = tableInfo?.Item1;
                if (tb != null)
                {
                    tb.GetKeyColumns()?.Select(s => s.Name)?.ForEach(field =>
                        OrderbyList.Add($"{Funs.FormatFieldName(tableInfo?.Item2, field, db.SqlDbProvider)} ASC"));
                }
            }
            if (OrderbyList.Count > 0)
            {
                orderbyStr = string.Join(", ", OrderbyList).Trim().ReplaceIgnoreCase("ORDER BY", "");
                orderbyStr = " ORDER BY " + orderbyStr;
            }
            else { orderbyStr = " ORDER BY " + db.SqlDbProvider.SqlDateNow; }
            //-----------------------------------
            var havingStr = "";
            if (HavingList.Count > 0)
            {
                havingStr = " HAVING " + string.Join(" ", HavingList).Trim()
                      .ReplaceIgnoreCase("HAVING", "").TrimPrefixName("AND").TrimPrefixName("OR");
            }
            var groupbyStr = "";
            if (GroupbyList.Count > 0)
            {
                groupbyStr = string.Join(", ", GroupbyList).Trim().ReplaceIgnoreCase("GROUP BY", "");
                groupbyStr = " GROUP BY " + groupbyStr;

                wheresStr = wheresStr + groupbyStr + havingStr + " ";
            }
            #endregion

            sqlent.Sql = string.Format(db.SqlDbProvider.GetCountSql(fromStr), wheresStr);
            totalNumber = db.GetSingle<long>(sqlent);

            if (pageIndex < 1) pageIndex = 1;
            if (pageSize < 1) pageSize = 10;
            var m = (pageIndex - 1) * pageSize + 1;
            //var n = pageIndex * pageSize;

            if (totalNumber > 0 && m <= totalNumber)
            {
                sqlent.Sql = db.SqlDbProvider.GetSelectPageSQL(fromStr, fieldsStr, wheresStr, orderbyStr, pageIndex, pageSize);

                var ret = db.Query<TClass>(sqlent);
                Dispose();
                return ret;
            }
            return new List<TClass>();
        }
        /// <summary>
        /// 分页查询返回实体集合
        /// </summary>
        /// <typeparam name="TClass"></typeparam>
        /// <param name="pagingInfo">分页信息</param>
        /// <returns></returns>
        public List<TClass> QueryPagingList<TClass>(BasePagingInfo pagingInfo) where TClass : class, new()
        {
            if (pagingInfo == null) return null;
            long totalNumber = 0;
            var ret = QueryPagingList<TClass>(pagingInfo.PageNumber, pagingInfo.PageSize, ref totalNumber);
            pagingInfo.Count = totalNumber;
            return ret;
        }
        //---------------------------------------------------------------------------------
#if !NET40
        /// <summary>
        /// 分页查询返回实体集合
        /// </summary>
        /// <typeparam name="TClass"></typeparam>
        /// <param name="pageIndex">第几页，从1开始</param>
        /// <param name="pageSize">每页多少</param>
        /// <param name="totalNumber">查询的记录总数量</param>
        /// <returns></returns>
        public Task<List<TClass>> QueryPagingListAsync<TClass>(int pageIndex, int pageSize, ref long totalNumber) where TClass : class, new()
        {
            return Task.FromResult(QueryPagingList<TClass>(pageIndex, pageSize, ref totalNumber));
        }
        /// <summary>
        /// 分页查询返回实体集合
        /// </summary>
        /// <typeparam name="TClass"></typeparam>
        /// <param name="pagingInfo">分页信息</param>
        /// <returns></returns>
        public Task<List<TClass>> QueryPagingListAsync<TClass>(BasePagingInfo pagingInfo) where TClass : class, new()
        {
            return Task.FromResult(QueryPagingList<TClass>(pagingInfo));
        }
#endif
        #endregion
        //-------------------------------------------------------------------------------------------------------------------------------
        #region override
        protected override bool Build(bool isCount = false)
        {
            if (isBuilded == true) return true;

            base.Build();
            //-----------------------------------
            var joinStr = "";
            if (JoingList.Count > 0)
            {
                joinStr = string.Join(" ", JoingList);
                fromStr += joinStr;
            }
            //-----------------------------------------------------------------------------------------------------------------
            var fieldsStr = FieldList.Count > 0 ? string.Join(", ", FieldList) : "*";
            var wheresStr = "1=1";
            if (WhereList.Count > 0)
            {
                wheresStr = string.Join(" ", WhereList).Trim()
                    .ReplaceIgnoreCase("WHERE", "").TrimPrefixName("AND").TrimPrefixName("OR");
            }
            //-----------------------------------
            var orderbyStr = "";
            if (OrderbyList.Count > 0)
            {
                orderbyStr = string.Join(", ", OrderbyList).Trim().ReplaceIgnoreCase("ORDER BY", "");
                orderbyStr = " ORDER BY " + orderbyStr;
            }
            //-----------------------------------
            var havingStr = "";
            if (HavingList.Count > 0)
            {
                havingStr = " HAVING " + string.Join(" ", HavingList).Trim()
                      .ReplaceIgnoreCase("HAVING", "").TrimPrefixName("AND").TrimPrefixName("OR");
            }
            var groupbyStr = "";
            if (GroupbyList.Count > 0)
            {
                groupbyStr = string.Join(", ", GroupbyList).Trim().ReplaceIgnoreCase("GROUP BY", "");
                groupbyStr = " GROUP BY " + groupbyStr;

                orderbyStr = groupbyStr + havingStr + " " + orderbyStr;
            }
            //-----------------------------------------------------------------------------------------------------------------
            if (isCount)
            {
                sqlent.Sql = string.Format(db.SqlDbProvider.GetCountSql(fromStr), wheresStr);
            }
            else
            {
                sqlent.Sql = string.Format(db.SqlDbProvider.GetSelectSQL(fromStr, fieldsStr, orderbyStr, _Top), wheresStr);
            }

            isBuilded = true;
            return true;
        }

        /// <summary>
        /// 返回sql脚本实体
        /// </summary>
        /// <returns></returns>
        public override SqlEntity GetSql(bool isCount = false) { Build(isCount); return sqlent; }

        public override void Dispose()
        {
            base.Dispose();

            OrderbyList.Clear();
            GroupbyList.Clear();
            HavingList.Clear();
            JoingList.Clear();
        }
        #endregion
    }
    #endregion
    #region SelectSqlBuilder<TClass>
    internal class SelectSqlBuilder<TClass> : SelectSqlBuilder, ISelectSqlBuilder<TClass> where TClass : class, new()
    {
        #region SelectSqlBuilder
        public SelectSqlBuilder(IDbHelper _db) : base(_db)
        {
            base.From<TClass>("");
        }
        #endregion

        #region Fields
        /// <summary>
        /// 添加查询字段
        /// </summary>
        /// <typeparam name="TClass"></typeparam>
        /// <param name="field"></param>
        /// <returns></returns>
        public ISelectSqlBuilder<TClass> Fields(Expression<Func<TClass, dynamic>> fields = null)
        {
            base.Fields(fields);
            return this;
        }
        /// <summary>
        /// 添加查询字段
        /// </summary>
        /// <param name="fields"></param>
        /// <returns></returns>
        public new ISelectSqlBuilder<TClass> Fields(params string[] fields)
        {
            base.Fields(fields);
            return this;
        }
        #endregion
        #region Top
        /// <summary>
        /// 最多返回记录数
        /// </summary>
        /// <param name="top"></param>
        /// <returns></returns>
        public new ISelectSqlBuilder<TClass> Top(int top = 1000)
        {
            base.Top(top);
            return this;
        }
        #endregion
        #region Where
        /// <summary>
        /// 添加条件表达式
        /// </summary>
        /// <typeparam name="TClass"></typeparam>
        /// <param name="where"></param>
        /// <returns></returns>
        public ISelectSqlBuilder<TClass> Where(Expression<Func<TClass, bool>> where, bool isAnd = true)
        {
            base.Where(where, isAnd);
            return this;
        }
        /// <summary>
        /// 添加条件表达式
        /// </summary>
        /// <param name="whereStr"></param>
        /// <returns></returns>
        public new ISelectSqlBuilder<TClass> Where(string whereStr, params CNDbParameter[] dbParameters)
        {
            base.Where(whereStr, dbParameters);
            return this;
        }
        #endregion
        #region OrderBy/OrderByDescending
        /// <summary>
        /// 按列排序，OrderBy(a => a.Time)
        /// </summary>
        /// <typeparam name="TMember"></typeparam>
        /// <param name="column">单个列</param>
        /// <returns></returns>
        public ISelectSqlBuilder<TClass> OrderBy(Expression<Func<TClass, dynamic>> column)
        {
            base.OrderBy(column);
            return this;
        }
        /// <summary>
        /// 按列倒向排序，OrderByDescending(a => a.Time)
        /// </summary>
        /// <param name="column">单个列</param>
        /// <returns></returns>
        public ISelectSqlBuilder<TClass> OrderByDescending(Expression<Func<TClass, dynamic>> column)
        {
            base.OrderByDescending(column);
            return this;
        }
        #endregion
        #region GroupBy
        /// <summary>
        /// 按列分组查询
        /// GroupBy<TClass>(a => a.Time) 或者 GroupBy<TClass>(a => new{a.Time,a.Name})
        /// </summary>
        /// <typeparam name="TClass"></typeparam>
        /// <param name="column">列集合</param>
        /// <returns></returns>
        public ISelectSqlBuilder<TClass> GroupBy(Expression<Func<TClass, dynamic>> column)
        {
            base.GroupBy(column);
            return this;
        }
        /// <summary>
        /// HAVING 子句可以筛选分组后的各组数据
        /// </summary>
        /// <typeparam name="TClass"></typeparam>
        /// <param name="expression">HAVING aggregate_function(column_name) operator value</param>
        /// <returns></returns>
        public ISelectSqlBuilder<TClass> Having(Expression<Func<TClass, bool>> having)
        {
            base.Having(having);
            return this;
        }
        #endregion

        #region Count/Exists
        /// <summary>
        /// 判断实体是否存在表中
        /// </summary>
        /// <returns></returns>
        public bool Exists(Expression<Func<TClass, bool>> where)
        {
            return base.Exists(where);
        }
        /// <summary>
        /// 通过条件查询表的记录数
        /// </summary>
        /// <returns></returns>
        public long Count(Expression<Func<TClass, bool>> where)
        {
            return base.Count(where);
        }
#if !NET40
        /// <summary>
        /// 异步通过条件查询表的记录数
        /// </summary>
        /// <param name="condition">条件</param>
        /// <returns></returns>
        public Task<long> CountAsync(Expression<Func<TClass, bool>> where)
        {
            return base.CountAsync(where);
        }
#endif
        #endregion
        #region Query
        /// <summary>
        /// 查寻返回实体集合
        /// </summary>
        /// <typeparam name="TClass"></typeparam>
        /// <returns></returns>
        public List<TClass> Query()
        {
            return base.Query<TClass>();
        }
        /// <summary>
        /// 查寻返回单行实体
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public TClass GetSingleRow()
        {
            return base.GetSingleRow<TClass>();
        }
        //---------------------------------------------------------------------------------
#if !NET40
        /// <summary>
        /// 异步返回实体集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public Task<List<TClass>> QueryAsync()
        {
            return base.QueryAsync<TClass>();
        }
        /// <summary>
        /// 异步返回单行实体
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public Task<TClass> GetSingleRowAsync()
        {
            return base.GetSingleRowAsync<TClass>();
        }
#endif
        #endregion

        #region QueryPagingList
        /// <summary>
        /// 分页查询返回实体集合
        /// </summary>
        /// <param name="pageIndex">第几页，从1开始</param>
        /// <param name="pageSize">每页多少</param>
        /// <param name="totalNumber">查询的记录总数量</param>
        /// <returns></returns>
        public List<TClass> QueryPagingList(int pageIndex, int pageSize, ref long totalNumber)
        {
            return base.QueryPagingList<TClass>(pageIndex, pageSize, ref totalNumber);
        }
        /// <summary>
        /// 分页查询返回实体集合
        /// </summary>
        /// <param name="pagingInfo">分页信息</param>
        /// <returns></returns>
        public List<TClass> QueryPagingList(BasePagingInfo pagingInfo)
        {
            return base.QueryPagingList<TClass>(pagingInfo);
        }
        //---------------------------------------------------------------------------------
#if !NET40
        /// <summary>
        /// 分页查询返回实体集合
        /// </summary>
        /// <param name="pageIndex">第几页，从1开始</param>
        /// <param name="pageSize">每页多少</param>
        /// <param name="totalNumber">查询的记录总数量</param>
        /// <returns></returns>
        public Task<List<TClass>> QueryPagingListAsync(int pageIndex, int pageSize, ref long totalNumber)
        {
            return base.QueryPagingListAsync<TClass>(pageIndex, pageSize, ref totalNumber);
        }
        /// <summary>
        /// 分页查询返回实体集合
        /// </summary>
        /// <param name="pagingInfo">分页信息</param>
        /// <returns></returns>
        public Task<List<TClass>> QueryPagingListAsync(BasePagingInfo pagingInfo)
        {
            return base.QueryPagingListAsync<TClass>(pagingInfo);
        }
#endif
        #endregion
        //-------------------------------------------------------------------------------------------------------------------------------
        #region override
        protected override bool Build(bool isCount = false)
        {
            if (isBuilded == true) return true;

            base.Build();
            //-----------------------------------------------------------------------------------------------------------------
            var fieldsStr = FieldList.Count > 0 ? string.Join(", ", FieldList) : "*";
            var wheresStr = "1=1";
            if (WhereList.Count > 0)
            {
                wheresStr = string.Join(" ", WhereList).Trim()
                    .ReplaceIgnoreCase("WHERE", "").TrimPrefixName("AND").TrimPrefixName("OR");
            }
            //-----------------------------------
            var orderbyStr = "";
            if (OrderbyList.Count > 0)
            {
                orderbyStr = string.Join(", ", OrderbyList).Trim().ReplaceIgnoreCase("ORDER BY", "");
                orderbyStr = " ORDER BY " + orderbyStr;
            }
            //-----------------------------------
            var havingStr = "";
            if (HavingList.Count > 0)
            {
                havingStr = " HAVING " + string.Join(" ", HavingList).Trim()
                      .ReplaceIgnoreCase("HAVING", "").TrimPrefixName("AND").TrimPrefixName("OR");
            }
            var groupbyStr = "";
            if (GroupbyList.Count > 0)
            {
                groupbyStr = string.Join(", ", GroupbyList).Trim().ReplaceIgnoreCase("GROUP BY", "");
                groupbyStr = " GROUP BY " + groupbyStr;

                orderbyStr = groupbyStr + havingStr + " " + orderbyStr;
            }
            //-----------------------------------------------------------------------------------------------------------------
            if (isCount)
            {
                sqlent.Sql = string.Format(db.SqlDbProvider.GetCountSql(fromStr), wheresStr);
            }
            else
            {
                sqlent.Sql = string.Format(db.SqlDbProvider.GetSelectSQL(fromStr, fieldsStr, orderbyStr, _Top), wheresStr);
            }

            isBuilded = true;
            return true;
        }

        #endregion
    }
    #endregion

}
